﻿using Frameworks;
using Networks;
using Networks.Data;
using SimpleJson;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

namespace game.lobby
{
    public class Lobby : MonoBehaviour
    {
        [Header("UI")]
        public Text chat_txt;
        public GameObject user_template;
        public InputField chat_InputField;
        public Button chat_btn;

        private List<UserEntity> _users;
        private List<ChatRecord> _chatRecords;
        private string _selectedUser;

        private void Awake()
        {
            _users = new List<UserEntity>();
            _chatRecords = new List<ChatRecord>();

            chat_btn.onClick.AddListener(sendChat);

            EventProxy.AddEventListener(Routes.ON_ADD, addUser);
            EventProxy.AddEventListener(Routes.ON_LEAVE, removeUser);
            EventProxy.AddEventListener(Routes.ON_CHAT, onChat);
        }

        private void Start()
        {
            updateUsers();
        }

        private void OnDestroy()
        {
            EventProxy.RemoveEventListener(Routes.ON_ADD, addUser);
            EventProxy.RemoveEventListener(Routes.ON_LEAVE, removeUser);
            EventProxy.RemoveEventListener(Routes.ON_CHAT, onChat);
        }




        #region User List
        private void updateUsers()
        {
            clearUsers();

            generateUser("All");
            _users[0].toggle.isOn = true;

            JsonObject jsonObject = Game.Instance.users;

            System.Object users = null;
            if (jsonObject.TryGetValue("users", out users))
            {
                string users_json = users.ToString();
                //Debug.Log(users_json);

                string[] users_info = users_json.Substring(1, users_json.Length - 2).Split(new Char[] { ',' });
                int length = users_info.Length;
                for (int i = 0; i < length; i++)
                {
                    string user_json = users_info[i].Replace("\"", "");

                    if (user_json == Game.Instance.myself.username) continue;

                    generateUser(user_json);
                }
            }
        }

        private void generateUser(string username)
        {
            GameObject go = Instantiate(user_template, user_template.transform.parent);
            go.SetActive(true);

            Toggle toggle = go.GetComponent<Toggle>();
            Text label = go.transform.Find("Label").GetComponent<Text>();

            label.text = username;
            toggle.onValueChanged.AddListener(value =>
            {
                if (value)
                {
                    _selectedUser = username;
                }
            });

            UserEntity userEntity = new UserEntity();
            userEntity.go = go;
            userEntity.toggle = toggle;
            userEntity.label = label;
            userEntity.user.username = username;
            _users.Add(userEntity);
        }

        private void clearUsers()
        {
            for (int i = 0; i < _users.Count; i++)
            {
                Destroy(_users[i].go);
            }
            _users.Clear();
        }

        private void addUser(EventData eventData)
        {
            if (eventData == null || eventData.target == null) return;

            JsonObject user = eventData.target as JsonObject;
            string username = user["user"].ToString();

            generateUser(username);

            chat_txt.text += string.Format("<color=yellow>{0}:加入房间\n</color>", username);
        }

        private void removeUser(EventData eventData)
        {
            if (eventData == null || eventData.target == null) return;

            JsonObject user = eventData.target as JsonObject;
            string username = user["user"].ToString();

            //var userEntites = _users.Where(u => u.username == username).ToList();
            var userEntity = _users.First(u => u.user.username == username);
            if (userEntity != null)
            {
                if (userEntity.toggle.isOn)
                {
                    _users[0].toggle.isOn = true;
                }

                chat_txt.text += string.Format("<color=red>{0}:离开房间\n</color>", userEntity.user.username);

                _users.Remove(userEntity);
                Destroy(userEntity.go);
            }
        }
        #endregion

        #region Chat
        private void sendChat()
        {
            if (!string.IsNullOrEmpty(chat_InputField.text) && !string.IsNullOrEmpty(_selectedUser))
            {
                if (_selectedUser == "All")
                {
                    chat("*", chat_InputField.text);
                }
                else
                {
                    // Chat with someone only.
                    chat(_selectedUser, chat_InputField.text);
                }
                chat_InputField.text = string.Empty;
            }
        }

        private void chat(string target, string content)
        {
            JsonObject message = new JsonObject();
            message.Add("rid", Game.Instance.myself.roomid);
            message.Add("content", content);
            message.Add("from", Game.Instance.myself.username);
            message.Add("target", target);

            _chatRecords.Add(new ChatRecord(Game.Instance.myself.username, content));
            chat_txt.text += string.Format("{0}:{1}\n", Game.Instance.myself.username, content);

            NetworkManager.Instance.Request(Routes.CHAT_SEND, message);
        }

        private void onChat(EventData eventData)
        {
            if (eventData == null || eventData.target == null) return;

            JsonObject message = eventData.target as JsonObject;

            System.Object msg = null, fromName = null, targetName = null;
            if (message.TryGetValue("msg", out msg) &&
                message.TryGetValue("from", out fromName) &&
                message.TryGetValue("target", out targetName))
            {
                if (fromName.ToString() == Game.Instance.myself.username) return;

                //Debug.Log(fromName.ToString() + ":" + msg.ToString() + " to " + targetName.ToString());
                _chatRecords.Add(new ChatRecord(fromName.ToString(), msg.ToString()));
                chat_txt.text += string.Format("{0}:{1}\n", fromName.ToString(), msg.ToString());
            }
        }
        #endregion
    }

    internal class UserEntity
    {
        public GameObject go;
        public Toggle toggle;
        public Text label;

        public UserData user;
        
        public UserEntity()
        {
            user = new UserData();
            user.roomid = Game.Instance.myself.roomid;
        }
    }
}